#ifndef __STRATEGY_H__
#define __STRATEGY_H__

#include <iostream>
#include <vector>
#include <algorithm>

class SortStrategy{
public:
    virtual void sort(std::vector<int>& ) = 0;
    void show(std::vector<int>& v){
        for(int i = 0;i < v.size();i++)
        {
            std::cout << v[i] << " ";
        }
        std::cout << std::endl;
    }

    void show(std::vector<int>&& v){
        for(int i = 0;i < v.size();i++)
        {
            std::cout << v[i] << " ";
        }
        std::cout << std::endl;
    }
};

class BubbleSortStrategy : public SortStrategy{
public:
    BubbleSortStrategy() = default;
    ~BubbleSortStrategy() = default;
    virtual void sort(std::vector<int>& ) override;
};

class InsertSortStrategy : public SortStrategy{
public:
    InsertSortStrategy() = default;
    ~InsertSortStrategy() = default;
    virtual void sort(std::vector<int>&) override;
};

class SelectionSortSrategy : public SortStrategy{
public:
    SelectionSortSrategy() = default;
    ~SelectionSortSrategy() = default;
    virtual void sort(std::vector<int>&) override;
};


class ShellSortStrategy :public SortStrategy{
public:
    ShellSortStrategy() = default;
    ~ShellSortStrategy() = default;
    virtual void sort(std::vector<int>&) override;
};

class MergeSortStrategy : public SortStrategy{
public:
    MergeSortStrategy() = default;
    ~MergeSortStrategy() = default;
    void merge(std::vector<int>& v,int left,int mid,int right);
    void mergeSort(std::vector<int>& v,int left,int right);
    virtual void sort(std::vector<int>&) override;
};

class QuickSortStrategy : public SortStrategy{
public:
    QuickSortStrategy() = default;
    ~QuickSortStrategy() = default;
    int privot(std::vector<int>& v,int left, int right);
    void quickSort(std::vector<int>& v,int left,int right);
    virtual void sort(std::vector<int>&) override;
};

class HeapSortStrategy : public SortStrategy{
public:
    HeapSortStrategy() = default;
    ~HeapSortStrategy() = default;
    void heapify(std::vector<int>& v,int index,int n);
    virtual void sort(std::vector<int>&) override;
};

class Sorter{
private:
    SortStrategy* m_strategy;
public:
    Sorter(SortStrategy* strategy):m_strategy(strategy){};
    ~Sorter(){
        if(m_strategy)
            delete m_strategy;
    };
    void setStrategy(SortStrategy* strategy);
    SortStrategy* getStrategy();
    void sort(std::vector<int>&);
    void show(std::vector<int>&);
};

#endif